﻿using System;
using System.Diagnostics;
using System.Net;
using System.Reflection;
using Fortune.API;
using Fortune.Attributes.API;
using Fortune.Context;
using Fortune.Log;
using Fortune.Util;
using WebSocketSharp.Server;

namespace Fortune.Loader
{
    /// <summary>
    /// 扫描包注册web socket接口
    /// </summary>
    public static class WebSocketAPILoader
    {
        private static readonly FortuneLogger logger = FortuneLogger.newInstance(typeof(WebSocketAPILoader));

        private const string IP = "127.0.0.1";
        private const int PORT = 9527;

        public static void load()
        {
            // #1 计时
            Stopwatch sw = new Stopwatch();
            sw.Start();

            // #2 初始化web socket
            WebSocketServer webSocketServer = new WebSocketServer(IPAddress.Parse(IP), PORT);

            // #3 注册API
            Type[] exportedTypes = typeof(RequestMappingAttribute).Assembly.GetExportedTypes();
            foreach (Type type in exportedTypes)
            {
                // 拿到类上的注解
                RequestMappingAttribute requestMapping = type.GetCustomAttribute<RequestMappingAttribute>();
                if (requestMapping == null)
                {
                    // 为空直接跳过
                    continue;
                }
        
                if (!TypeUtil.hasImplementedRawGeneric(type, typeof(WebSocketBehavior)))
                {
                    // 非WebSocketBehavior的类不会被加载
                    logger.info($"在非{typeof(WebSocketBehavior).FullName}类上标注了{typeof(RequestMappingAttribute)}，接口{requestMapping.url}将不会生效");
                    continue;
                }

                if (!requestMapping.enable)
                {
                    // enable不为true不会被加载
                    logger.warning($"enable = {requestMapping.enable}, {requestMapping.url}不会被加载");
                    continue;
                }
                
                webSocketServer.AddWebSocketService(requestMapping.url, () =>
                {
                    // 添加web socket接口实例
                    WebSocketBehavior webSocketBehavior = (WebSocketBehavior)Activator.CreateInstance(type);
                    return webSocketBehavior;
                });
                logger.info($"加载{requestMapping.url}, type={type.FullName}");
                // Console.Out.WriteLine($"加载{api.url}, type={type.FullName}");
            }
            
            // #4 启动web socket监听
            webSocketServer.Start();
            
            // #5 注册server到造化上下文
            FortuneContext.webSocketServer = webSocketServer;

            logger.info($"加载完成，共加载{webSocketServer.WebSocketServices.Count}个接口，耗时{sw.ElapsedMilliseconds}ms");
            logger.info($"Web Socket Server在 {IP}:{PORT} 上启动");
            sw.Stop();
        }
    }
}